#include "ThreadUpload.h"
#include "StaticConfig.h"
#include <StringTool.h>

ThreadUpload::ThreadUpload(int id, OnThreadTaskEnded cb) : objectId(id), cbTaskEnd(cb)
{    
    hasNewTask = false;
    isRun = true;
    thread = std::thread(&ThreadUpload::workerThreadFunc, this);
}

ThreadUpload::~ThreadUpload()
{
    if (isRun)
    {
        isRun = false;
        if (thread.joinable())
            thread.join();
    }
}

void ThreadUpload::setTasks(std::vector<std::filesystem::path>& files)
{    
    newFiles = files;
    hasNewTask = true;
}

void ThreadUpload::getStatInfo(UpStatInfo& info)
{
    info = upStatInfo;
}

void ThreadUpload::workerThreadFunc()
{   
    httpUpClient.setServiceAddress(StaticConfig::mWorkConfig.file_service_url);

    while (isRun)
    {
        while (!hasNewTask && isRun)
        {
            std::this_thread::sleep_for(std::chrono::milliseconds(100));
        }

        for (std::filesystem::path& it: newFiles)
        {
            if (!isRun)
                break;

            // 上传单个文件
            bool success = uploadFile(it);
            upStatInfo.total_count++;
            if (!success)
                upStatInfo.fail_count++;
            else 
            {
                // 处理上传后文件（删除或重命名）
                if (StaticConfig::mWorkConfig.delete_after_upload)
                    fs::remove(it);                
                else 
                {
                    auto newFile = it;
                    newFile.replace_extension("uploaded");
                    fs::rename(it, newFile);
                }
            }            
        }   

        hasNewTask = false;
        newFiles.clear();

        if (cbTaskEnd)
            cbTaskEnd(objectId);
    }

    printf("[%s][%d]:return ... ",__FUNCTION__,objectId);
}

bool ThreadUpload::uploadFile(const std::filesystem::path& filePath) 
{
    try {

        // 检查文件是否存在且为普通文件
        if (!fs::exists(filePath) || !fs::is_regular_file(filePath)) {
            std::cout << ("文件不存在或不是普通文件: " + filePath.string());
            return false;
        }        

        fs::path dir = filePath.parent_path();
        fs::path filename = filePath.filename();

        std::wstring localFile = StringTool::string2wstring(filePath.u8string(), CP_UTF8);
        std::wstring localFolder = StringTool::string2wstring(dir.u8string(), CP_UTF8);

        int skip_len = StaticConfig::root_path_utf8.size();
        if (StaticConfig::root_path_utf8[StaticConfig::root_path_utf8.size() - 1] != L'/'
            && StaticConfig::root_path_utf8[StaticConfig::root_path_utf8.size() - 1] != '\\')
        {
            skip_len++;
        }

        std::wstring remoteFolder = localFolder.substr(skip_len);
        std::replace(remoteFolder.begin(), remoteFolder.end(), L'-', L'/');
        auto remotePath = remoteFolder + L"/" + StringTool::string2wstring(filename.u8string(), CP_UTF8);

        //return 0;
        return httpUpClient.pushFile(localFile, remotePath);
    }
    catch (...) {
        return false;
    }
}
